// function MethodDecorator(
//     target: Object,      // 类的原型对象（静态方法时是构造函数）
//     propertyKey: string | symbol,  // 方法名
//     descriptor: PropertyDescriptor  // 方法描述符
// ) {
//     // 可以修改 descriptor.value（原方法）实现增强
// }
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
// 你看到的这个输出结构：
// {
//     kind: 'method',
//         name: 'getName',
//     static: false,
//     private: false,
//     access: { has: [Function], get: [Function] },
//     metadata: undefined,
//         addInitializer: [Function]
// }
// 这正是 ECMAScript 装饰器提案 Stage 3 的标准格式，不再是原来的 target, propertyKey, descriptor 三个参数！
// const MethodDecorator = (
//     value: (this: Person, ...args: any[]) => any,
//     context: ClassMethodDecoratorContext
// ) => {
//     console.log(value)
//     console.log(context)
//     // 返回新函数，替代原方法
//     return function (this: Person, ...args: any[]) {
//         console.log("调用前");
//         const result = value.apply(this, args); // 调用原方法
//         console.log("调用后");
//         return result + "（已装饰）";
//     };
// }
// 装饰器工厂传递参数
// function MethodDecorator(param: string) {
//     return function (
//         value: any,
//         context: ClassMethodDecoratorContext
//     ): any {
//         console.log("param:", param);
//         console.log("原函数:", value);
//         console.log("context:", context);
//         // 返回新的方法函数
//         return function (this: any, ...args: any[]) {
//             console.log("调用前");
//             const result = value.apply(this, args);
//             console.log("调用后");
//             return result + `（已装饰，参数是${param}）`;
//         };
//     };
// }
//
// class DectorPerson {
//     address: string = "上海";
//
// // @MethodDecorator("我是get")
// //     get getAddress() {
// //         return this.address
// //     }
// //
// //     @MethodDecorator("我是set")
// //     set setAddress(value: string) {
// //         this.address = value
// //     }
// //
// //     @MethodDecorator("我是静态函数")
// //     static getAge() {
// //         return 18;
// //     }
//
//     @MethodDecorator("我是撒大声地")
//     getName() {
//         return "的撒娇大数据";
//     }
// }
//
// const useDectorPerson = new DectorPerson();
// console.log(useDectorPerson.getName())
// 介绍context中access的get/set使用
function AccessorDecorator(param) {
    return function (value, context) {
        if (typeof value !== "function") {
            throw new TypeError("Function expected"); // value 应该是 getter/setter 函数
        }
        console.log("param:", param);
        console.log("原函数:", value);
        console.log("context:", context);
        return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            var zks = function () {
                if (context.kind === 'getter') {
                    return "我是get";
                }
                else {
                    return "我是set";
                }
            };
            return zks();
        };
        // return {
        //     get() {
        //         console.log("调用前", param);
        //         const result = context.access.get!(this);
        //         console.log("调用后");
        //         return result + "（装饰器增强）";
        //     },
        //     set(val: any) {
        //         console.log("设置前");
        //         context.access.set!(this, val);
        //         console.log("设置后");
        //     }
        // };
    };
}
var PersonDe = function () {
    var _a;
    var _instanceExtraInitializers = [];
    var _get_address_decorators;
    var _set_address_decorators;
    return _a = /** @class */ (function () {
            function PersonDe() {
                this._address = (__runInitializers(this, _instanceExtraInitializers), "上海");
            }
            Object.defineProperty(PersonDe.prototype, "address", {
                // @ts-ignore
                get: function () {
                    return this._address;
                },
                // @ts-ignore
                set: function (value) {
                    this._address = value;
                },
                enumerable: false,
                configurable: true
            });
            return PersonDe;
        }()),
        (function () {
            var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
            _get_address_decorators = [AccessorDecorator("我是访问器")];
            _set_address_decorators = [AccessorDecorator("我是set")];
            __esDecorate(_a, null, _get_address_decorators, { kind: "getter", name: "address", static: false, private: false, access: { has: function (obj) { return "address" in obj; }, get: function (obj) { return obj.address; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(_a, null, _set_address_decorators, { kind: "setter", name: "address", static: false, private: false, access: { has: function (obj) { return "address" in obj; }, set: function (obj, value) { obj.address = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        })(),
        _a;
}();
var usep = new PersonDe();
usep.address = "北京";
console.log(usep.address);
